#ifndef FILESYS_BUFFERCACHE_H
#define FILESYS_BUFFERCACHE_H

#include "filesys/inode.h"
#include "filesys/off_t.h"
#include "threads/synch.h"
#include <list.h>
#include <stdbool.h>

#define MAX_BFC_SIZE 64

/* This structture define a buffer cache's entry, it contains
   information that is to be used by eviction policy, in our case
   we are going to use the clock algorithm */
struct bfc_entry
  {
    struct inode *inode;    /* This entry in the buffer cache is owned
                               by a sigle file */
                               
    off_t offset;           /* Specify what segment of the file,
                               this entry represents */
                               
    uint8_t bytes;          /* Bytes that this entry contains */
    
    bool dirty;             /* If this field is set, then this entry must
                               be written back in disk */
                               
    bool accessed;          /* If this field is set, then this entry has
                               been either read or written */
                               
    uint32_t rds;           /* Number of readers or writers for this entry */
    
    bool evictable;         /* This avoid that this entry can be evicted in 
                                an inconsistent state */
    
    void *addr;             /* What is the address that this entry owns */
    
    struct lock lock;       /* Lock to make syncronization when necessary */
    
    struct list_elem elem;  /* Element in the buffer cache */
  };
  
/* Functions that describe the basic functionality of the Buffer Cache */
uint32_t buffer_cache_write (struct inode *, off_t, const void *, uint32_t);
uint32_t buffer_cache_read (struct inode *, off_t, void *, uint32_t);

struct bfc_entry *buffer_cache_get_entry (struct inode *, off_t);
struct bfc_entry *buffer_cache_look_up (struct inode *, off_t);

// Called on filesys start up
void init_buffer_cache (void);

// Called by timer_interrup() to keep on save the information stored by the bc
void buffer_cache_write_back (void);

// Once a file has been closed, saves the changes back in the disk
void buffer_cache_flush (void);

#endif


